package org.smr.ministore.test.conf;

import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.smr.comp.mybatis.conf.DataSourceProperties;
import org.smr.comp.mybatis.conf.MyBatisConfiguration;
import org.smr.comp.mybatis.conf.MyBatisProperties;
import org.smr.comp.mybatis.utils.PageInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.sql.DataSource;
import java.util.Properties;

@Configuration
@EnableConfigurationProperties({DataSourceProperties.class, MyBatisProperties.class})
public class MybatisScanConfiguration {


    @Autowired
    private DataSourceProperties dataSourceProperties;


    private Logger logger = LoggerFactory.getLogger(MyBatisConfiguration.class);

    private ResourceLoader resourceLoader;

    @Autowired
    private MyBatisProperties myBatisProperties;


    public MybatisScanConfiguration(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    /**
     * @Title: getDataSource
     * @Description: 创建数据源
     * @param @return
     * @return DataSource
     * @throws
     */
    @Bean
    @Primary
    @ConditionalOnMissingBean
    public DataSource getDataSource(){
        Properties props = new Properties();
        props.put("driverClass", dataSourceProperties.getDriverClassName());
        props.put("url", dataSourceProperties.getUrl());
        props.put("username",dataSourceProperties.getUsername());
        props.put("password", dataSourceProperties.getPassword());



        try {
            return DruidDataSourceFactory.createDataSource(props);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @Title: sqlSessionFactory
     * @Description:  根据数据源创建SqlSessionFactory
     * @param @param ds
     * @param @return
     * @param @throws Exception
     * @return SqlSessionFactory
     * @throws
     */
    @Bean
    @Primary
    @ConditionalOnMissingBean
    public SqlSessionFactory sqlSessionFactory() throws Exception{


        if (this.myBatisProperties.isCheckConfigLocation() && StringUtils.hasText(this.myBatisProperties.getConfigLocation())) {
            Resource resource = this.resourceLoader.getResource(this.myBatisProperties.getConfigLocation());
            Assert.state(resource.exists(), "Cannot find config location: " + resource
                    + " (please add config file or check your Mybatis configuration)");
        }


        logger.info("初始化:{}",SqlSessionFactory.class);
        SqlSessionFactoryBean sfb = new SqlSessionFactoryBean();
        sfb.setVfs(SpringBootVFS.class);
        sfb.setDataSource(getDataSource());
        //下边两句仅仅用于*.xml文件，如果整个持久层操作不需要使用到xml文件的话（只用注解就可以搞定），则不加
        if (StringUtils.hasLength(myBatisProperties.getTypeAliasesPackage())) {
            sfb.setTypeAliasesPackage(myBatisProperties.getTypeAliasesPackage());
        }
        logger.info("SqlSessionFactory setTypeAliasesPackage:{}", myBatisProperties.getTypeAliasesPackage());

        if (!ObjectUtils.isEmpty(myBatisProperties.getMapperLocations())) {
            sfb.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(myBatisProperties.getMapperLocations()));
        }
        logger.info("SqlSessionFactory setMapperLocations:{}", myBatisProperties.getMapperLocations());

        sfb.setPlugins(new Interceptor[]{new PageInterceptor()});
        logger.info("SqlSessionFactory setPlugins:{}", PageInterceptor.class);

        return sfb.getObject();
    }


    @Bean
    @ConditionalOnMissingBean
    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
        ExecutorType executorType = this.myBatisProperties.getExecutorType();
        if (executorType != null) {
            return new SqlSessionTemplate(sqlSessionFactory, executorType);
        } else {
            return new SqlSessionTemplate(sqlSessionFactory);
        }
    }

    /*
    @Bean
    public DB startDb(){
        DB db = null;
        try {
            DBConfigurationBuilder configBuilder = DBConfigurationBuilder.newBuilder();
            configBuilder.setPort(3307);
            configBuilder.setDataDir("/home/blade/Documents/db");
            db = DB.newEmbeddedDB(configBuilder.build());
            db.start();
        } catch (ManagedProcessException e) {
            e.printStackTrace();
        }
        return db;
    }
    */


}
